import 'package:common_utils/common_utils.dart';
import 'package:flutter/cupertino.dart';

import '../../components/page_status.dart';

abstract class ListPageImpl<T> {
  int get pageIndex;

  int get pageSize;

  PageStatus get pageStatus;

  List<T> get dataList;

  //加载数据
  Future loadData();

  //刷新数据
  Future refresh();

  //加载更多
  Future loadMore();
}

abstract class DetailPageImpl<T> {
  String? get id;

  set id(String? id);

  T? get detailModel;

  set detailModel(T? model);

  //加载数据
  Future loadData();

  //参数校验
  bool verify();

  //提交
  Future<bool> submit();
}

abstract class DetailPageProvider<T> extends ChangeNotifier {
  String? id;

  T? detailModel;

  //加载数据
  Future loadData() async {
    clearController();
  }

  //参数校验
  external bool verify();

  //提交
  external Future<bool> submit();

  //删除
  external Future<bool> delete();

  //新增
  external Future<bool> add();

  final Map<String, TextEditingController> _inputControllerMap = {};

  TextEditingController? getTextEditingController(String key, {String? data}) {
    TextEditingController? controller = _inputControllerMap[key];
    if (controller == null) {
      controller = TextEditingController(text: data ?? '');
      _inputControllerMap[key] = controller;
    }
    return controller;
  }

  TextEditingController? initTextEditingController(String key, {String? data}) {
    TextEditingController? controller = _inputControllerMap[key];
    if (controller == null) {
      controller = TextEditingController();
    }
    controller.text = data ?? '';
    _inputControllerMap[key] = controller;
    return controller;
  }

  clearController() {
    _inputControllerMap.clear();
  }

  clearControllerData() {
    _inputControllerMap.values.forEach((element) {
      element.clear();
    });
  }

  final Map<String, dynamic> _cachePageData = {};

  Map<String, dynamic> get cachePageData => _cachePageData;

  putCachePageData(String key, dynamic data) {
    _cachePageData[key] = data;
  }

  dynamic getCachePageData(String? key, {Function()? queryData}) {
    if (ObjectUtil.isEmpty(key)) {
      return null;
    }
    var data = _cachePageData[key];
    if (data == null && queryData != null) {
      queryData.call().then((result) {
        if (result != null) {
          putCachePageData(key!, result);
          notifyListeners();
        }
      });
    }
    return data;
  }
}

abstract class ListPageProvider<T> extends ChangeNotifier implements ListPageImpl<T> {
  @override
  List<T> dataList = [];
  @override
  int pageIndex = 1;

  @override
  int get pageSize => 20;

  @override
  PageStatus pageStatus = PageStatus.NORMAL;

  bool isLoading = false;

  // //参数校验
  // external bool verify();

  @override
  Future refresh() async {
    if (isLoading) {
      return;
    }
    pageIndex = 1;
    dataList = [];
    isLoading = true;
    await loadData();
    isLoading = false;
  }

  @override
  Future loadMore() async {
    if (isLoading) {
      return;
    }
    pageIndex++;
    isLoading = true;
    await loadData();
    isLoading = false;
  }

  final Map<String, TextEditingController> _inputControllerMap = {};

  TextEditingController? getTextEditingController(String key, {String? data}) {
    TextEditingController? controller = _inputControllerMap[key];
    if (controller == null) {
      controller = TextEditingController(text: data ?? '');
      _inputControllerMap[key] = controller;
    }
    return controller;
  }

  TextEditingController? initTextEditingController(String key, {String? data}) {
    TextEditingController? controller = _inputControllerMap[key];
    if (controller == null) {
      controller = TextEditingController();
    }
    controller.text = data ?? '';
    _inputControllerMap[key] = controller;
    return controller;
  }

  clearController() {
    _inputControllerMap.clear();
  }

  clearControllerData() {
    _inputControllerMap.values.forEach((element) {
      element.clear();
    });
  }

  final Map<String, dynamic> _cachePageData = {};

  putCachePageData(String key, dynamic data) {
    _cachePageData[key] = data;
  }

  Map<String, dynamic>? getCachePageData(String? key, {Function()? queryData}) {
    if (ObjectUtil.isEmpty(key)) {
      return null;
    }
    var data = _cachePageData[key];
    if (data == null && queryData != null) {
      queryData.call().then((result) {
        if (result != null) {
          putCachePageData(key!, result);
          notifyListeners();
        }
      });
    }
    return data;
  }
}
